package cn.buk.tms.flight.util;

import cn.buk.common.JsonResult;
import cn.buk.common.dto.eterm.PnrFlightDto;
import cn.buk.common.dto.eterm.PnrPassengerDto;
import cn.buk.qms.OrderUtil;
import cn.buk.tms.common.constant.TmsOrderConstant;
import cn.buk.tms.common.dto.base.BasePriceDto;
import cn.buk.tms.common.dto.flight.BaseFlightOrderFlightDto;
import cn.buk.tms.entity.order.flight.*;
import cn.buk.tms.flight.request.FlightOrderRequestDto;
import cn.buk.tms.flight.dto.response.FlightOrderResponseDto;
import cn.buk.common.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.buk.common.Constant.DATE_YYYY_MM_DD;
import static cn.buk.common.Constant.PSG_TYPE_ADU;
import static cn.buk.tms.common.constant.TmsConstant.FLIGHT_AUTO_TICKETING_NONE;

/**
 * @author yfdai
 */
public class FlightOrderUtil {

  private FlightOrderUtil() {

  }

  /**
   * 判断机票订单是否成人订单
   * @param orderInfo
   * @return
   */
  public static boolean isAdultFlightOrder(FlightOrder orderInfo) {
    for (FlightOrderPassenger psg : orderInfo.getPassengers()) {
      if (psg.getPsgType() != PSG_TYPE_ADU) {
        return false;
      }
    }
    return true;
  }

  /**
   * 判断机票订单的供应商是否不是自动出票的供应商
   * @return
   */
  public static boolean isNotAutoTicketingSupplier(FlightOrder flightOrder) {
    return flightOrder.getSupplier() == null || flightOrder.getSupplier().getIsBsp() == FLIGHT_AUTO_TICKETING_NONE;
  }

  /**
   * 判断机票订单的航班日期是否已过
   * @param orderInfo
   * @return true-有起飞时间已过的航班
   */
  public static boolean isFlightOrderExpired(FlightOrder orderInfo) {
    boolean expired = false;
    for (FlightOrderFlight flt : orderInfo.getFlights()) {
      Optional<Date> flightDate = convertToDate(flt.getFlight().getDdate().trim());

      if (flightDate.isPresent()) {
        final Date fltDate = flightDate.get();
        final Date today = DateUtil.getCurDate();
        if (fltDate.getTime() < today.getTime()) {
          expired = true;
        } else if (fltDate.getTime() == today.getTime()) {
          int hour = Integer.parseInt(flt.getFlight().getDtime().substring(0, 2));
          if (hour <= DateUtil.getCurrentHour()) {
            expired = true;
          }
        }
      } else {
        expired = true;
      }

      if (expired) {
        break;
      }
    }

    return expired;
  }

  public static void clean(FlightOrder order) {
    if (order == null) {
      return;
    }

    for (FlightOrderFlight flt : order.getFlights()) {
      flt.setOrder(null);
    }

    for (FlightOrderPassenger psg : order.getPassengers()) {
      psg.setOrder(null);
    }

    for (FlightOrderExtra info : order.getExtras()) {
      info.setOrder(null);
    }
  }

  public static void cleanFlightRefundOrder(FlightRefundOrder order) {
    if (order == null) {
      return;
    }

    for(FlightRefundOrderDetail detail: order.getFlights()) {
      detail.setOrder(null);
    }
  }

  public static void cleanFlightChangeOrder(FlightChangeOrder order) {
    if (order == null) {
      return;
    }

    for (FlightChangeOrderDetail detail : order.getFlights()) {
      detail.setOrder(null);
    }
  }

  public static String getItineraryTypeDesc(int type) {
    switch (type) {
      case 1:
        return "行程单";
      case 2:
        return "发票";
      case 3:
        return "信息单";
      default:
        return "";
    }
  }

  /**
   * 校验航班时间是否符合要求
   * @param dtime
   * @return
   */
  public static boolean validateFlightTime(final String dtime) {
    final String regEx = "^[0-2][0-9]{3}([+]1)?$";
    final Pattern pattern = Pattern.compile(regEx);

    Matcher m = pattern.matcher(dtime);
    return m.find();
  }

  public static FlightOrderRequestDto createDtoByFlightOrder(FlightOrder flightOrder) {
    FlightOrderRequestDto dto = new FlightOrderRequestDto();

    BeanUtils.copyProperties(flightOrder, dto);
    dto.setOrderStatus(flightOrder.getStatus());

    // 成人部分的价格
    BasePriceDto priceDto = dto.getAdultPrice();
    priceDto.setPrice(flightOrder.getPrice());
    priceDto.setParValue(flightOrder.getParvalue());
    priceDto.setTax(flightOrder.getTax());
    priceDto.setInsurance(flightOrder.getInsurance());
    priceDto.setServiceCharge(flightOrder.getServiceCharge());
    priceDto.setCommission(flightOrder.getCommission());
    priceDto.setCommission2(flightOrder.getCommission2());
    priceDto.setDiscount(flightOrder.getDiscount());

    // 儿童部分的价格
    priceDto = dto.getChildPrice();
    priceDto.setPrice(flightOrder.getChdPrice());
    priceDto.setParValue(flightOrder.getChdParvalue());
    priceDto.setTax(flightOrder.getChdTax());
    priceDto.setInsurance(flightOrder.getChdInsurance());
    priceDto.setServiceCharge(flightOrder.getChdServiceCharge());

    priceDto.setCommission(flightOrder.getChdCommission());
    priceDto.setCommission2(flightOrder.getChdCommission2());

    priceDto.setDiscount(flightOrder.getChdDiscount());


    // 婴儿部分的价格
    priceDto = dto.getInfantPrice();
    priceDto.setPrice(flightOrder.getInfPrice());
    priceDto.setParValue(flightOrder.getInfParvalue());
    priceDto.setTax(flightOrder.getInfTax());
    priceDto.setInsurance(flightOrder.getInfInsurance());
    priceDto.setServiceCharge(flightOrder.getInfServiceCharge());

    priceDto.setCommission(flightOrder.getInfCommission());
    priceDto.setCommission2(flightOrder.getInfCommission2());

    priceDto.setDiscount(flightOrder.getInfDiscount());


    dto.setFlights(new ArrayList<>());
    dto.setPassengers(new ArrayList<>());

    for(FlightOrderFlight flt0: flightOrder.getFlights()) {
      PnrFlightDto flt1 = new PnrFlightDto();
      BeanUtils.copyProperties(flt0, flt1);

      dto.getFlights().add(flt1);
    }

    for(FlightOrderPassenger psg0: flightOrder.getPassengers()) {
      PnrPassengerDto psg1 = new PnrPassengerDto(0, "");
      BeanUtils.copyProperties(psg0, psg1);

      dto.getPassengers().add(psg1);
    }


    return dto;
  }

  public static FlightOrder convertTo(FlightOrderRequestDto dto) {
    // 将DTO中的内容转化到FlightOrder中
    FlightOrder info = new FlightOrder();
    BeanUtils.copyProperties(dto, info, "flights", "passengers");

    //转化价格 begin
    OrderUtil.copyFlightOrderPrice(dto, info);
    //转化价格 end

    info.setTktl(dto.getTktlDate());

//        info.setFlights(null);
//        info.setPassengers(null);

    // 航段信息
    OrderUtil.copyFlightOrderFlights(dto, info);


    // 乘机人信息
    OrderUtil.copyFlightOrderPassengers(dto, info);


    return info;
  }

  private static Optional<Date> convertToDate(String strDate) {
    try {
      Date fltDate = DateUtil.convertToDate(strDate, DATE_YYYY_MM_DD);
      return Optional.of(fltDate);
    } catch (Exception ex) {
      return Optional.empty();
    }
  }

  /**
   * 获取机票订单中的最早航班日期
   * @param detail
   * @return
   */
  public static Date getMinDepartureDate(FlightOrderResponseDto detail) {
    Date minDate = null;
    for (BaseFlightOrderFlightDto fltDto : detail.getFlights()) {
      if (fltDto.getDdate() == null) {
        continue;
      }

      if (minDate == null || minDate.getTime() > fltDto.getDdate().getTime() ) {
        minDate = fltDto.getDdate();
      }
    }

    return minDate;
  }

  /**
   * 验证订单是否符合自动开票的条件
   */
  public static JsonResult validateOrderInfoByAutoTicketing(FlightOrder orderInfo) {

    for (FlightOrderPassenger psg : orderInfo.getPassengers()) {
      if (psg.getPsgType() != 0) {
        return JsonResult.createJsonResult(-1, "暂未开通非成人票");
      }
    }

    if (orderInfo.getAutoTicketing() == 0) {
      return JsonResult.createJsonResult(-2, "未设置自动开票");
    }

    if (orderInfo.getIntlTicket() == 1 || orderInfo.getSegCount() > 2) {
      return JsonResult.createJsonResult(-3, "自动开票目前仅支持国内最多两程");
    }

    if (orderInfo.getAutoTicketing() == 2 && orderInfo.getAutoTicketingPrice() <= 0) {
      return JsonResult.createJsonResult(-4, "请确定BSP开票的价格");
    }

    if (orderInfo.getStatus() != TmsOrderConstant.FLIGHT_ORDER_STATUS_TICKETING_ACCEPTED) {
      return JsonResult.createJsonResult(-5, "订单状态不符合要求");
    }

    return JsonResult.createJsonResult(1);
  }

  /**
   * 判断机场三字代码是否准确
   * @param code 机场代码
   * @return true or false
   */
  public static boolean isValidAirportCode(final String code) {
    return StringUtils.trimToEmpty(code).length() == 3;
  }

  /**
   * 简易判断航班号是否符合要求, 长度在4-7之间
   * @param flightNo
   * @return
   */
  public static boolean isValidFlightNo(final String flightNo) {
    var  val =  StringUtils.trimToEmpty(flightNo);
    return val.length() >= 4 && val.length() <= 7;
  }

  public static boolean isValidSubClass(final String subClass) {
    var  val =  StringUtils.trimToEmpty(subClass);
    return val.length() >= 1 && val.length() <= 2;
  }

  /**
   * 判断机型代码是否三位或空
   * @param aircraft
   * @return
   */
  public static boolean isValidAircraft(final String aircraft) {
    var  val =  StringUtils.trimToEmpty(aircraft);
    return val.length() == 0 || val.length() == 3;
  }

}
